/*
  Copyright (C) 2011, Kyungjoo Kim
  
  This file is part of UHM (Unassembled HyperMatrix) sparse direct solver.
  
  All rights reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.
  
  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.
  
  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  Also add information on how to contact you by electronic and paper mail.
  
  
  Kyungjoo Kim
  iamkyungjoo@gmail.com
*/
#include "uhm/common.hxx"
#include "uhm/const.hxx"
#include "uhm/util.hxx"

#include "uhm/object.hxx"

#include "uhm/operation/scheduler.hxx"
#include "uhm/operation/mesh.hxx"
#include "uhm/operation/element.hxx"

#include "uhm/mesh/node.hxx"
#include "uhm/mesh/element.hxx"

#include "uhm/matrix/uhm/matrix.hxx"

#include "uhm/mesh/mesh.hxx"

namespace uhm {
  // --------------------------------------------------------------
  // ** tree and partition
  bool build_tree(Mesh m) {
    bool r_val;
    //#pragma omp parallel
    {
      //#pragma omp single nowait
      r_val = build_tree_var_4(m);
    }
    return r_val;
  }
  bool partition_mesh(Mesh m, int nparts) {
    bool r_val;
    //#pragma omp parallel
    {
      //#pragma omp single nowait
      r_val = partition_mesh_var_1(m, nparts);
    }
    return r_val;
  }

  // --------------------------------------------------------------
  // ** pragma wrapper
  void decompose_with_free(Mesh m) {
    decompose_with_free(m, m->get_decomposition_method());
  }
  void decompose_with_free(Mesh m, int decomposition) {
#pragma omp parallel                                                            
    {
#pragma omp single nowait   
      m->decompose_with_free(decomposition);
    }
  }

  void decompose_without_free(Mesh m) {
    decompose_without_free(m, m->get_decomposition_method());
  }
  void decompose_without_free(Mesh m, int decomposition) {
#pragma omp parallel                                                            
    {
#pragma omp single nowait   
      m->decompose_without_free(decomposition);
    }
  }

  void solve_1(Mesh m) { solve_1(m, m->get_decomposition_method()); }
  void solve_1(Mesh m, int decomposition) {
#pragma omp parallel
    {
#pragma omp single nowait
      m->solve_1(decomposition);
    }
  }

  void solve_2(Mesh m) { solve_2(m, m->get_decomposition_method()); }
  void solve_2(Mesh m, int decomposition) {
#pragma omp parallel
    {
#pragma omp single nowait
      m->solve_2(decomposition);
    }
  }

  void solve(Mesh m) { solve(m, m->get_decomposition_method()); }  
  void solve(Mesh m, int decomposition) {
#pragma omp parallel
    {
#pragma omp single nowait
      {
        m->solve_1(decomposition);
        m->solve_2(decomposition);
      }
    }
  }

  void check_1(Mesh m) { check_1(m, m->get_decomposition_method()); }
  void check_1(Mesh m, int decomposition) {
#pragma omp parallel
    {
#pragma omp single nowait
      m->check_1(decomposition);
    }
  }

  void check_2(Mesh m) { check_2(m, m->get_decomposition_method()); }
  void check_2(Mesh m, int decomposition) {
#pragma omp parallel
    {
#pragma omp single nowait
      m->check_2(decomposition);
    }
  }
  
  void check(Mesh m) { check(m, m->get_decomposition_method()); }
  void check(Mesh m, int decomposition) {
    //#pragma omp parallel
    {
      //#pragma omp single nowait
      m->check(decomposition);
    }
  }

}
